#include "StopCriteria.h"


StopCriteria::StopCriteria(void)
{
}


StopCriteria::~StopCriteria(void)
{
}


void StopCriteria::setOldSolution(vector<double>* solution)
{
	this->m_vOldSolution.resize(solution->size());
	for(int i=0;i<solution->size();i++){
		this->m_vOldSolution[i]=(*solution)[i];
	}
}
void StopCriteria::setOldObjFun(double objFun){
	this->m_nOldObjFun = objFun;
}

void StopCriteria::setBestObjFun(double objFun){
	this->m_nBestObjFun = objFun;
}

double StopCriteria::calculateStepSize(double rho, OptData* optData, int iter)
{

	if(iter<1){
		m_nDynamic=0;
		return 1;
	}


	if(m_vOldSolution.size()!=optData->getWeightTotal()->size()){
		setOldSolution(optData->getWeightTotal());

		return rho;
	}

	double MaxDiff=0;

	for(int i=0;i<optData->getWeightTotal()->size();i++){
		if(MaxDiff<abs((*optData->getWeightTotal())[i]-m_vOldSolution[i])){
			MaxDiff = abs((*optData->getWeightTotal())[i]-m_vOldSolution[i]);
		}
	}

	cout<< MaxDiff <<"\t";
	if(MaxDiff>0.02){
		return 1;
	}else{
		double size = pow(0.99995,m_nDynamic);
		m_nDynamic++;
		if(size > 0.05){
			return size;
		}else{
			return 0.05;
		}
	}
}

bool StopCriteria::checkStop(OptData* optData, double objFun, int iter)
{
	bool result = false;

	if (this->m_vSolutionCoef.size() != optData->getBeamletNumTotal()) {
		this->m_vSolutionCoef.resize(optData->getBeamletNumTotal());
		for (int indexPoint = 0; indexPoint < optData->getDijTotal()->size(); indexPoint++) {
			for (int indexBeamlet = 0; indexBeamlet < (*optData->getDijTotal())[indexPoint].size(); indexBeamlet++) {
				this->m_vSolutionCoef[indexBeamlet] += (*optData->getDijTotal())[indexPoint][indexBeamlet];
			}
		}
	}

	double diffSol=0;
	double diffObj=0;
	if(iter<1){
		if(optData->getWeightTotal()->size()!=m_vOldSolution.size()){
			setOldSolution(optData->getWeightTotal());
		}
		setOldObjFun(objFun);
		setBestObjFun(objFun);
		m_nContinuousStop=false;
		m_nContinousStopNum=0;
		return false;
	}else{

		for(int i=0;i<optData->getWeightTotal()->size();i++){
			diffSol+=abs((*optData->getWeightTotal())[i]-m_vOldSolution[i])*m_vSolutionCoef[i];
		}
		diffSol = diffSol / optData->getBeamletNumTotal();
		setOldSolution(optData->getWeightTotal());

		diffObj = abs(objFun-m_nBestObjFun);
		if(objFun<m_nBestObjFun){
			m_nBestObjFun = objFun;
		}

		cout<<"diffSol "<<diffSol<<" diffObj "<<diffObj<<"\t";

		if(diffSol<m_nEpsnoSol&&diffObj<m_nEpsnoObj){
			if(m_nContinousStopNum>=50&&m_nContinuousStop==true){
				return true;
			}else{
				m_nContinousStopNum++;
				m_nContinuousStop=true;
			}
		}else{
			m_nContinuousStop=false;
			m_nContinousStopNum=0;
		}

		if(iter>=this->m_nMaxIter){
			if(this->m_nMaxIter == 0){
				return false;
			}else{
				return true;
			}

		}
	}

	return result;
}
